package cn.structure.linear.queue;

/**
 * 循环队列（数组实现）
 *
 * @author dunlingzi
 */
public class CircularQueue {

    private int[] array;
    /**
     * 队头
     */
    private int font;
    /**
     * 队尾
     */
    private int rear;

    public CircularQueue(int capacity) {
        this.array = new int[capacity];
    }

    /**
     * 入队操作
     * 循环队列的核心是计算队尾下标：
     * （队尾下标 + 1） % 队列长度  = 队尾下标
     * 队列队尾的位置是在入队元素位置 + 1的地方是队尾的位置，
     * 要保证队尾下标不会超过数组长度，则用取余数据长度作为限定。
     *
     * @param element 入队数据
     * @throws Exception 抛出异常
     */
    public void enQueue(int element) throws Exception {
        //（队尾下标 + 1） % 队列长度 来计算
        //以数组长度来进行循环，所以需要整除取余数组长度
        if ((rear + 1) % array.length == font) {
            throw new Exception("队列已满");
        }
        array[rear] = element;
        // （队尾下标 + 1） % 队列长度  ==>计算队尾下标
        rear = (rear + 1) % array.length;
    }

    /**
     * 出队操作
     */
    public int deQueue() throws Exception {
        if (rear == font) {
            throw new Exception("队列已空");
        }
        int deQueueElement = array[font];
        font = (font + 1) % array.length;
        return deQueueElement;
    }

    public void out() {
        //注意被移出去的数据
        for (int i = font; i != rear; i = (i + 1) % array.length) {
            System.out.println(array[i]);
        }
    }

}
